import { _decorator, Animation, AnimationClip, Color, Component, EventMouse, Graphics, HorizontalTextAlignment, instantiate, Label, Node, Overflow, Prefab, resources, Sprite, UITransform, Vec3, VerticalTextAlignment, EventTarget } from 'cc';
import { DiceController } from '../DiceController';
import { ThrowDiceController } from '../ThrowDiceController';
import { eventTarget } from '../../util/EventUtil';
import { CELL_TYPE } from '../storyboard/RebelDinosaurController'
const { ccclass, property } = _decorator;

@ccclass('NormalCellController')
export abstract class NormalCellController extends Component {
    protected explore: boolean = false;
    
    protected id: number;
    protected linkId: Array<number>;
    protected type: number;
    protected prefab: Prefab;
    protected x: number;
    protected y: number;
    protected sizeX: number;
    protected sizeY: number;
    protected value: Array<number>;
    protected cellControllerArray: Array<NormalCellController> = new Array();
    protected diceManager: ThrowDiceController;
    protected event: Array<object>;

    public node: Node;

    constructor(node: Node, diceManager: ThrowDiceController, type: number) {
        super();
        this.node = node;
        this.diceManager = diceManager;
        this.type = type;
    }

    public loadPrefabCell(prefabPath: string, data: object): NormalCellController {
        this.setProperty(data);
        resources.load(prefabPath, Prefab, (err, prefab) => {
            this.prefab = prefab;
            const item = this.createPrefab(data);
            this.node.addChild(item);
        });

        this.customLoadPrefabCell(prefabPath, data);

        return this;
    }

    protected setProperty(data: Object) {
        this.id = data['id'];
        this.linkId = data['link'];
        this.x = data['positionX'];
        this.y = data['positionY'];
        this.sizeX = data['contentSizeX'];
        this.sizeY = data['contentSizeY'];
        this.value = data['value'];
        this.event = data['event'];
    }

    protected createPrefab(data: Object) {
        let item: Node = instantiate(this.prefab);
        item.setWorldPosition(new Vec3(this.x, this.y));

        item.getComponent(UITransform).setContentSize(this.sizeX, this.sizeY)
        item.getChildByName('Background').getComponent(UITransform).setContentSize(this.sizeX, this.sizeY);
        item.getChildByName('ExploreX').getComponent(UITransform).setContentSize(this.sizeX, this.sizeY);
        item.getChildByName('Value').getComponent(UITransform).setContentSize(this.sizeX, this.sizeY);

        item.getChildByName('Value').getComponent(Label).string = `${this.value[0]}`;
        item.getChildByName('Value').getComponent(Label).verticalAlign = VerticalTextAlignment.CENTER
        item.getChildByName('Value').getComponent(Label).horizontalAlign = HorizontalTextAlignment.CENTER

        item.on('mouse-down', this.perClickToNormalCell, this);

        this.customCreatePrefab(item, data)

        return item;
    }

    protected addAnimation(item: Node) {
        resources.load("animation/DrawExploreX", AnimationClip, (err, clip) => {
            item.getComponent(Animation).addClip(clip, "DrawExploreX");
        });
    }

    // 前置操作判断用户是否能走该单元格
    private perClickToNormalCell(event: EventMouse): void {
        let node = event.currentTarget;

        // 先判定是否有骰子相加是该点数
        // 在该单元格附近是否有起始单元格或者被探索过的单元格
        // let temp = this.judgeDice(node) && this.hasExploreCell(node);
        // if (!temp) {
        //     return;
        // }

        this.emitEvent(node);
        this.clickToNormalCell(event);
    }

    // 判断骰子相加是否可以得到被点单元格
    private judgeDice(node: NormalCellController): boolean {
        for (let num of this.value) {
            let temp: Map<number, DiceController> = new Map();
            for (let dice of this.diceManager.getDices()) {
                // 如果这个骰子没有使用过且骰子点数小于 num 
                // 因为每一个格子是否可以前往是需要骰子组合的
                // 所以如果一个数字小于骰子则不可能组合直接排除
                if (!dice.IsUsed() && dice.getNum() < num) {
                    if (temp.get(dice.getNum()) == null) {
                        temp.set(num - dice.getNum(), dice);
                    } else {
                        temp.get(dice.getNum()).setUsed(true);
                        dice.setUsed(true);
                        return true;
                    }
                }
            }
        }

        return false;
    }

    // 判断周围是否有被探索过的单元格或起始单元格
    private hasExploreCell(node: NormalCellController): boolean {
        for (let cell of this.getCellControllerArray()) {
            if (cell.type == CELL_TYPE.START.number || cell.isExplore()) {
                return true;
            }
        }

        return false;
    }

    // 发送的事件信息
    private emitEvent(node: NormalCellController): void {
        this.event.forEach((value, index, array) => {
            eventTarget.emit(value['name'], value['number'])
        })
    }

    protected clickToNormalCell(event: EventMouse) {
        if (this.explore) {
            // 该单元该以被探索
            return;
        }

        this.explore = true;

        let node = event.currentTarget;

        // 加载反转动画
        // node.getComponent(Animation).play('DrawExploreX')

        // 画 X
        let graphics = node.getChildByName('ExploreX').getComponent(Graphics)

        let x = node.getComponent(UITransform).width - this.sizeX / 2 - 10;
        let y = node.getComponent(UITransform).height - this.sizeY / 2 - 10;

        graphics.moveTo(-x, -y);
        graphics.lineTo(x, y);
        graphics.moveTo(-x, y);
        graphics.lineTo(x, -y);
        graphics.stroke();

        // 定制化操作
        this.customClickToCell(event);
    }

    // public abstract loadPrefabCell(data: Object): NormalCellController;
    protected abstract customLoadPrefabCell(prefabPath: string, data: object): void;
    protected abstract customClickToCell(event: EventMouse): void
    protected abstract customCreatePrefab(item: Node, data: object): void;

    public setCellControllerMap(id: number, cellController: NormalCellController): void {

    }

    public addCellControllerArray(cellController: NormalCellController) {
        this.cellControllerArray.push(cellController);
    }

    public getCellControllerArray(): Array<NormalCellController> {
        return this.cellControllerArray;
    }

    public getId(): number {
        return this.id;
    }

    public getLinkId(): Array<number> {
        return this.linkId;
    }

    public getType(): number {
        return this.type;
    }

    public isExplore(): boolean {
        return this.explore;
    }

    public getValue(): Array<number> {
        return this.value;
    }
}


